package com.itheima.service.impl;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.MessageConstant;
import com.itheima.dao.BookingOrderDao;
import com.itheima.entity.BookingPagesBean;
import com.itheima.entity.PageResult;
import com.itheima.entity.Result;
import com.itheima.pojo.*;
import com.itheima.service.BookingOrderService;
import com.itheima.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = BookingOrderService.class)
@Transactional
public class BookingOrderServiceImpl implements BookingOrderService {
    @Autowired
    private BookingOrderDao bookingOrderDao;
    @Reference
    private Order order;
    @Autowired
    private OrderServiceImpl orderServiceImpl;

    //根据订单id查询所有的套餐id
    @Override
    public List<Integer> findSetmealIdsByOrderId(Integer id) {
        return bookingOrderDao.findSetmealIdsByOrderId(id);
    }

    //分页查询
    @Override
    public PageResult findPage(BookingPagesBean queryPageBean) {
        //得到页码
        Integer currentPage = queryPageBean.getCurrentPage();
        //得到每页记录数
        Integer pageSize = queryPageBean.getPageSize();
        //得到查询条件
        String queryString = queryPageBean.getQueryString();//sads
        //得到日期
        Date[] queryDate = queryPageBean.getQueryDate();
        //得到(微信丶手机预约)下拉框
        String queryOrderType = queryPageBean.getQueryOrderType();
        //得到(已到诊丶未到诊) 下拉框
        String queryOrderStatus = queryPageBean.getQueryOrderStatus();
        PageHelper.startPage(currentPage, pageSize);
        //创建map集合 用于存储所有的查询条件
        HashMap<String, Object> map = new HashMap<>();
        //将查询条件存储到map集合
        map.put("currentPage",currentPage);
        map.put("pageSize",pageSize);
        map.put("queryString",queryString);
        map.put("queryDate",queryDate);
        map.put("queryOrderType",queryOrderType);
        map.put("queryOrderStatus",queryOrderStatus);
        Date startDate = null;
        Date endDate = null;
        if (queryDate != null && queryDate.length > 0) {
            startDate = queryDate[0];
            endDate = queryDate[1];
        }/*else{
            startDate= "1970-01-01";
            endDate = */
        Page all = bookingOrderDao.selectByCondition(queryString, startDate, endDate, queryOrderType, queryOrderStatus);
        List result = all.getResult();
        long total = all.getTotal();
        return new PageResult(total, result);
    }

    /**
     *修改(已到诊丶未到诊)开关的状态按钮
     */
    @Override
    public void statusEdit(Map map) {
        bookingOrderDao.statusEdit(map);
    }

   /* @Override
    public PageResult findPage(Map map) throws Exception {
        //1.拿出日期
        List<String> queryDate =(List<String>) map.get("queryDate");
        //2.设置起始时间和结束时间
        String startDate;
        String endDate;
        //3.添加判断
        if (queryDate.size() == 0 || queryDate == null){
            //3.1 说明用户压根没有使用时间搜索栏,这时我们就查询所有事件
            startDate = "1970-01-01";
            endDate = "2200-12-31";
        }else{
            //3.2 说明用户使用了事件搜索栏,
            startDate = queryDate.get(0);
            endDate = queryDate.get(1);
        }
        //4.拿到预约状态
        String queryOrderStatus = (String) map.get("queryOrderStatus");
        //5.拿到搜索状态
        String queryOrderType = (String) map.get("queryOrderType");
        //6.拿到搜索条件
        String queryString = (String) map.get("queryString");
        //7.拿到当前显示页面和每页显示条目数
        Integer currentPage = (Integer) map.get("currentPage");
        Integer pageSize = (Integer) map.get("pageSize");
        PageHelper.startPage(currentPage, pageSize);

        //把更改后的数据重新封装到map中
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("startDate", startDate);
        stringObjectHashMap.put("endDate", endDate);
        stringObjectHashMap.put("queryOrderStatusString", queryOrderStatus);
        stringObjectHashMap.put("queryOrderTypeString", queryOrderType);
        stringObjectHashMap.put("queryString", queryString);
        Page<Map> page = bookingOrderDao.findByPageAndCondition(stringObjectHashMap);
        List<Map> rows = page.getResult();
        for (Map row : rows) {
            //把查出来的日期转化为字符串 ，方便在前端显示
            row.put("orderDate", DateUtils.parseDate2String((Date) row.get("orderDate")));
        }
        return new PageResult(page.getTotal(), rows);
    }*/


    //删除预约订单方法
    //删除前要先判断当前预约订单和地址之间是否有关联,因为已经有了关联关系,所以不能直接删
    @Override
    public void delete(Integer id) {
       //解除与address(地址表)之间的关联关系
        bookingOrderDao.deleteOrederAndAddress(id);
        //解除关系后丶 删除预约订单
        bookingOrderDao.deleteOrderById(id);
    }

    /**
     * 修改预约订单方法
     *
     * @param map
     * @param setmealId
     */
    @Override
    public void edit(Map map, Integer setmealId) throws Exception {
        //参数集合传递过来获取到订单信息
        String name = (String) map.get("name"); //会员姓名
        String phoneNumber = (String) map.get("phoneNumber");//会员手机号
        String orderDateStr = (String) map.get("orderDate"); //会员预约的日期(字符串)
        Integer oid = (Integer) map.get("orderId");
        String orderType = (String) map.get("orderType");//预约类型
        String orderStatus = (String) map.get("orderStatus");//预约状态
        String dept = String.valueOf(map.get("dept")); //地址信息
        System.out.println(oid);
        map.put("setmealId", setmealId); //将订单的id存入集合中
        //根据手机号码改会员名字
        bookingOrderDao.editMemberByPhone(map);
        //根据手机号查询该会员的id
        Integer memberId = bookingOrderDao.findIdByPhoneNumber(phoneNumber);
        //根据会员id 修改 订单信息
        map.put("memberId", memberId);
        //判断是否有预约设置,调用isOrderSedtting()方法
        if (isOrderSedtting(orderDateStr) != null) {
            //有预约设置,判断是否已预约满了
            if (isOrder(orderDateStr)) {
                //如果可以预约的
                Order order = new Order();
                order.setSetmealId(setmealId);
                order.setOrderDate(DateUtils.parseString2Date(orderDateStr));
                order.setMemberId(memberId);
                order.setOrderStatus(orderStatus);
                order.setOrderType(orderType);
                //查询机构名对应的ID
                Integer addressId = bookingOrderDao.findAddressByDept(dept);
                //修改订单成功后修改订单和地址的关系
                Boolean aBoolean = bookingOrderDao.editOrederAndAddress(oid, addressId);
                //查询是否是重复预约
                List<Order> orders = bookingOrderDao.findByCondition(order);
                if (orders == null || orders.isEmpty() || aBoolean == true) {
                    //修改订单基本信息及对应套餐
                    bookingOrderDao.editOrderAndSetmeal(map);
                } else {
                    throw new Exception("重复预约");
                }
            } else {
                throw new Exception(orderDateStr + "预约已满");
            }
        } else {
            //没有预约设置
            throw new Exception("请在" + orderDateStr + "进行预约设置");
        }
    }

    //通过订单id查询预约订单所有信息
    @Override
    public Map<String, Object> findOrderById(Integer id) {
        Map<String, Object> map = bookingOrderDao.findOrderById(id);
        return map;
    }

    /**
     * 新增电话预约套餐
     *
     * @param map
     */
    @Override
    public Result addPhoneOrder(Map map) throws Exception {
        //拿出手机号码和姓名
        String phoneNumber = (String) map.get("phoneNumber");
        String name = (String) map.get("name");
        //拿出会员id和预约日期和套餐id
        String orderDateStr = (String) map.get("orderDate"); //字符串类型的
        //拿到机构的地址ID
        Integer addressId = (Integer) map.get("dept");
        Integer setmealId = (Integer) map.get("setmealId");
        //日期转化
        Date orderDate = DateUtils.parseString2Date(orderDateStr);

        //创建 Order对象 把数据设置进去 未到诊 和电话预约  是定的
        Order order = new Order();
        order.setOrderDate(orderDate);
        order.setOrderStatus("未到诊");
        order.setOrderType("电话预约");
        order.setSetmealId(setmealId);
        //判断该用户是否为会员

        Member memberByPhone = bookingOrderDao.findMemberByPhone(phoneNumber);


        //定义会员id
        Integer memberId;
        if (memberByPhone == null) {
            //说明不是会员,在会员表里面新增一条信息
            Member member = new Member();
            member.setName(name);
            member.setPhoneNumber(phoneNumber);
            //添加会员信息
            bookingOrderDao.addNameAndPhone(member);
            //拿到新增会员的id
            memberId = member.getId();
            order.setMemberId(memberId);

            if (isOrderSedtting(orderDateStr) != null) {
                //说明这一天 有预约设置
                if (isOrder(orderDateStr)) {
                    //没约满
                    //调用add方法 把该预约信息存进数据库
                    bookingOrderDao.addOrder(order);
                    //添加成功获取添加成功的ID
                    Integer orderId = order.getId();
                    //添加成功之后,添加订单和地址之间的关系
                    bookingOrderDao.addOrderAndAddress(orderId, addressId);
                    //添加成功后，拿到当前的预约设置
                    OrderSetting orderSetting = isOrderSedtting(orderDateStr);
                    //把已预约人数加1
                    orderSetting.setReservations(orderSetting.getReservations() + 1);
                    //调用预约设置方法,实现已预约人数的改变
                    bookingOrderDao.editReservationsByOrderDate(orderSetting);
                } else {
                    //throw new Exception(orderDateStr + "预约已满");
                    return new Result(false, MessageConstant.ORDER_FULL);
                }
            } else {
                //throw new Exception("请在" + orderDateStr + "进行预约设置");
                return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);
            }
        } else {
            //说明是会员 id从查询结果拿
            memberId = memberByPhone.getId();
            order.setMemberId(memberId);
            if (isOrderSedtting(orderDateStr) != null) {
                if (isOrder(orderDateStr)) {
                    //说明预约未满可以预约
                    List<Order> orders = bookingOrderDao.findByCondition(order);
                    if (orders == null || orders.size() < 1) {
                        //调用add方法 把该预约信息存进数据库
                        bookingOrderDao.addOrder(order);
                        //添加成功获取添加成功的ID
                        Integer orderId = order.getId();
                        //添加成功之后,添加订单和地址之间的关系
                        bookingOrderDao.addOrderAndAddress(orderId, addressId);
                        //添加成功后，拿到当前的预约设置
                        OrderSetting orderSetting = isOrderSedtting(orderDateStr);
                        //把已预约人数加1
                        orderSetting.setReservations(orderSetting.getReservations() + 1);
                        //调用预约设置方法,实现已预约人数的改变
                        bookingOrderDao.editReservationsByOrderDate(orderSetting);
                    } else {
                        //说明有相同的预约，则不往下执行
                        //throw new Exception("会员 " + name + "重复预约");
                        return new Result(false, MessageConstant.HAS_ORDERED);
                    }
                } else {
                    //throw new Exception(orderDateStr + "预约已满");
                    return new Result(false, MessageConstant.ORDER_FULL);
                }
            } else {
                //throw new Exception("请在" + orderDateStr + "进行预约设置");
                return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);
            }
        }
        return new Result(true,MessageConstant.ADD_BOOKINGORDER_SUCCESS);
    }




    /**
     * 判断预约人数是否已满(参数传递字符串类型的时间)
     *
     * @param orderDateStr
     * @return
     */
    private boolean isOrder(String orderDateStr) {
        Integer count = bookingOrderDao.isFull(orderDateStr);
        //添加判断
        if (count == 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 拿到当前预约设置判断的方法
     *
     * @param orderDateStr
     * @return
     */
    private OrderSetting isOrderSedtting(String orderDateStr) throws Exception {
        //调用时间解析工具类 将字符串类型的解析成date类型
        Date date = DateUtils.parseString2Date(orderDateStr);
        //返回可预约的日期
        return bookingOrderDao.findByOrderDate(date);
    }


    //建立Order表和Address关系
    public void setOrderAndAddress(Integer orderId, Integer addressId) {
        //设置订单表和地址表之间多对多关联关系,添加中间表数据(主要是获得order表中新生成的ID)
        //创建map集合,存取id
        HashMap<String, Integer> map = new HashMap<>();
        map.put("orderId", orderId);
        map.put("addressId", addressId);
        bookingOrderDao.setOrderAndAddress(map);
    }
}
